fix(agent-core): honor abort signal in WebSearch and FetchURL tools - #1108
fix(agent-core): honor abort signal in WebSearch and FetchURL tools#1108Caldalis wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: a1c5358 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Clean threading of the abort signal through every layer — nice work. Tests covering both providers are solid. One small thing: |
Thanks addressed in a follow-up: MoonshotFetchURLProvider.fetch now rethrows when the caller's signal is aborted, so a cancelled request surfaces as a clean abort instead of kicking off a fallback fetch. Genuine Moonshot failures (network errors) still fall back to the local fetcher as before. Added a test covering the abort doesn't fall back path. |
120345b to
a41a165
Compare
|
I've rebased this onto the latest
|
Thread the turn's AbortSignal through the FetchURL/WebSearch tools and the UrlFetcher / WebSearchProvider interfaces into every underlying fetch, so cancelling a turn aborts the in-flight request instead of leaving it running. Covers the Moonshot fetch/search providers and the local fallback fetcher's per-hop request. A caller-driven abort of the Moonshot fetch is re-thrown instead of retrying the local fallback, so cancellation surfaces cleanly.
a41a165 to
a1c5358
Compare
Phase 1 — Non-PR issues (5): - MoonshotAI#94: Read tool status now reports both MAX_LINES and MAX_BYTES when both limits are hit (was: else-if chain only reported the first). Fixed in v1 (agent-core) and v2 (agent-core-v2). Added test for dual-limit case. - MoonshotAI#250: KIMI_MODEL_* env config no longer gives OpenAI/Anthropic models the Kimi default capabilities (image_in, thinking). DEFAULT_CAPABILITIES is now a per-provider-type map: kimi gets ['image_in','thinking'], openai/anthropic get []. Fixed in v1 (env-model.ts) and v2 (envOverlay.ts). Added 2 tests. - MoonshotAI#1972: Skill descriptions exceeding the 250-char model listing limit now emit a warning via onWarning during loadRoots, so the user knows the model sees a truncated version. Added 2 tests (warns / does not warn). - MoonshotAI#1982: Added disabled_skills config denylist. config.toml now accepts disabled_skills = ['skill-name']. Matching skills (case-insensitive) are hidden from getSkill, getPluginSkill, listSkills, listInvocableSkills, register, loadRoots, and the TUI slash menu. Wired through SessionSkillConfig, resolveSessionSkillConfig, and TOML serialization. Added 3 tests. - MoonshotAI#2224: Plugin-qualified skill names (e.g. 'superpowers:systematic-debugging') are now resolved by the native Skill tool. Falls back to getPluginSkill when bare-name getSkill misses and the name contains ':'. Fixed in v1 (skill-tool.ts) and v2 (skillTool.ts). Added 2 tests. Phase 2 — PR-matching issues (5): - MoonshotAI#1008 (PR MoonshotAI#1096): Web UI session archive relabeled from 'Archive' to 'Delete'. Confirm message now states the action is irreversible (en + zh). - MoonshotAI#1106 (PR MoonshotAI#1108): WebSearch and FetchURL tools now forward the abort signal from ExecutableToolContext through to fetch() calls. Updated provider interfaces (WebSearchProvider, UrlFetcher) and all 3 provider implementations (MoonshotWebSearch, MoonshotFetchURL, LocalFetchURL). Updated 2 tests. - MoonshotAI#1050 (PR MoonshotAI#1052): kosong streaming response loop now has an idle timeout (default 60s, configurable via idleTimeoutMs). Replaced bare for-await with manual iterator + Promise.race against timeout. Throws APITimeoutError on idle. Fixed in v1 (kosong/generate.ts) and v2 (agent-core-v2/generate.ts). Added 9 tests. - MoonshotAI#1148 (PR MoonshotAI#1208): max_tokens/max_output_tokens now clamped to 128k ceiling in openai-legacy generate() and openai-responses withMaxCompletionTokens() + generate(). Kimi provider left unchanged (upstream clamping is intentional). Added 4 tests. - MoonshotAI#1273 (PR MoonshotAI#1276): Added KimiCore.dispose() which iterates all live sessions and calls session.close() via Promise.allSettled. Wired into CoreProcessService.dispose(). Idempotent. Added 5 tests. Skipped (already fixed in fork): MoonshotAI#1539, MoonshotAI#244, MoonshotAI#1218. Checklist: .tmp/upstream-tracking/ISSUE-RESOLUTION-CHECKLIST.md
Related Issue
Resolve #1106
Problem
WebSearchandFetchURLignored the per-callAbortSignal. Cancelling a turn(Ctrl-C / turn abort) did not cancel an in-flight network request — it kept
running in the background, holding a connection, and on a slow or hung server it
lingered until undici's default timeouts.
Every other I/O-bound builtin tool (Bash, Grep, Agent, AskUser) already threads
ctx.signalinto its work; the two web tools were the only exception, with nocomment explaining the omission, so this reads as an overs
intentional choice.
What changed
signalto theUrlFetcherandWebSearchProvideroption objects.FetchURLTool/WebSearchToolnow forwardctx.signal they destructured onlytoolCallId`).LocalFetchURLProvider,MoonshotFetchURLProvider, andMoonshotWebSearchProviderpass the signal to the underlyingfetch(), which aborts both the header wait and the body read. The Moonshot → loc options object, so the signal flows through automatically.fetch.This matches the existing cancellation pattern used by Bash/Grep/Agent and keeps the change focused. The touched interfaces (
UrlFetcher/WebSearchProvider) are internal toagent-coreand are rface.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update